#ifndef _BITARRAY_H
#define _BITARRAY_H

#include <ostream>
#include <fstream>
#include <iostream>

using namespace std;

#include "types.h"


/* ZLIB */

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"

#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
#  include <fcntl.h>
#  include <io.h>
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
#  define SET_BINARY_MODE(file)
#endif

#define CHUNK 16384


/* ZLIB */


class BitArray{
	private:
		byte* buff;
		uint64 length;
		uint32 byteLen;
		uint32 trueSize;
		bool copy;
		struct
		{
			uint32 lowerSize64;
			uint32 firstOverIndex8;
			uint64* buff64;
			uint64* lastElem64;
			
		}extraInfo;
		void bignum_inc(uint64 *beg,uint64* end);
		void clearPadding();
		void generateExtraInfo();
		
	public:
		BitArray(byte* b,uint32 len,bool cpy);
		BitArray(char* filename);
		BitArray(uint32 len,bool val);
		BitArray(const BitArray &b);
		BitArray();
		~BitArray();
		bool operator[](uint64 index);
		void operator+=(uint64 index);
		void operator++();
		void operator++(int32);
		BitArray& operator=(const BitArray &b);
		uint64 countBits(bool type);
		void setBit(bool b,uint64 Idx);
		uint64 getSize();
		uint32 getMinByteSize();
		uint32 getByteSize();
		bool operator==(BitArray &b);
		bool operator!=(BitArray &b);
		bool operator<(BitArray &b);
		byte getByte(uint32 index);
		uint64 getUint64(uint32 index);
		uint32 getTrueSize();
		bool arithmIsEqual(BitArray &b);
		void fill(uint64 ln,bool val);
		void crapHash512(ubyte* sum);
		void write(byte* filename);
		void write(byte* filename,uint32 len);
		void clear();
		bool isClear();
		uint64 getMinBitSize();
		uint32 getApproxCompressedSize();
		friend ostream& operator<< (ostream& os , BitArray& a);
};

#endif
